/*     */ package com.zimbra.cs.mailbox;
/*     */ 
/*     */ import com.google.common.base.CharMatcher;
/*     */ import com.google.common.base.Objects;
/*     */ import com.google.common.base.Objects.ToStringHelper;
/*     */ import com.google.common.collect.Sets;
/*     */ import com.zimbra.common.mailbox.Color;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.ArrayUtil;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.StringUtil;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.db.DbMailItem;
/*     */ import com.zimbra.cs.db.DbTag;
/*     */ import com.zimbra.soap.mail.type.RetentionPolicy;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Collection;
/*     */ import java.util.List;
/*     */ import java.util.Set;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class Tag
/*     */   extends MailItem
/*     */ {
/*     */   public static final int NONEXISTENT_TAG = -32;
/*     */   private boolean isListed;
/*     */   private RetentionPolicy retentionPolicy;
/*     */   static final String FLAG_NAME_PREFIX = "\\";
/*     */   
/*     */   public static class NormalizedTags
/*     */   {
/*  43 */     private static final String[] NO_TAGS = new String[0];
/*     */     private String[] tags;
/*     */     
/*     */     NormalizedTags(Mailbox mbox, String[] tagsFromClient) throws ServiceException
/*     */     {
/*  48 */       this(mbox, tagsFromClient, true);
/*     */     }
/*     */     
/*     */     NormalizedTags(Mailbox mbox, String[] tagsFromClient, boolean create) throws ServiceException {
/*  52 */       assert (mbox.isTransactionActive()) : "cannot instantiate NormalizedTags outside of a transaction";
/*     */       int i;
/*  54 */       if (ArrayUtil.isEmpty(tagsFromClient)) {
/*  55 */         this.tags = NO_TAGS;
/*     */       } else {
/*  57 */         Set<Tag> tlist = Sets.newLinkedHashSet();
/*  58 */         for (String tag : tagsFromClient) {
/*     */           try {
/*  60 */             tlist.add(mbox.getTagByName(tag));
/*     */           }
/*     */           catch (MailServiceException.NoSuchItemException nsie)
/*     */           {
/*  64 */             if (create) {
/*     */               try {
/*  66 */                 tlist.add(mbox.createTagInternal(-1, tag, new Color((byte)0), false));
/*     */               }
/*     */               catch (ServiceException e) {
/*  69 */                 if (!e.getCode().equals("mail.ALREADY_EXISTS")) {
/*  70 */                   throw e;
/*     */                 }
/*     */               }
/*     */             }
/*     */           }
/*     */         }
/*  76 */         this.tags = new String[tlist.size()];
/*  77 */         i = 0;
/*  78 */         for (Tag t : tlist) {
/*  79 */           this.tags[(i++)] = t.getName();
/*     */         }
/*     */       }
/*     */     }
/*     */     
/*     */     public NormalizedTags(Collection<String> tagsFromDB) {
/*  85 */       this(tagsFromDB == null ? null : (String[])tagsFromDB.toArray(new String[tagsFromDB.size()]));
/*     */     }
/*     */     
/*     */     public NormalizedTags(String[] tagsFromDB) {
/*  89 */       this.tags = (tagsFromDB == null ? NO_TAGS : tagsFromDB);
/*     */     }
/*     */     
/*     */     String[] getTags() {
/*  93 */       return this.tags;
/*     */     }
/*     */     
/*     */     public String toString()
/*     */     {
/*  98 */       return this.tags.toString();
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   Tag(Mailbox mbox, MailItem.UnderlyingData ud)
/*     */     throws ServiceException
/*     */   {
/* 111 */     this(mbox, ud, false);
/*     */   }
/*     */   
/*     */   Tag(Mailbox mbox, MailItem.UnderlyingData ud, boolean skipCache) throws ServiceException {
/* 115 */     super(mbox, ud, skipCache);
/* 116 */     if ((this.mData.type != MailItem.Type.TAG.toByte()) && (this.mData.type != MailItem.Type.FLAG.toByte())) {
/* 117 */       throw new IllegalArgumentException();
/*     */     }
/* 119 */     if (this.retentionPolicy == null)
/*     */     {
/*     */ 
/* 122 */       this.retentionPolicy = new RetentionPolicy();
/*     */     }
/*     */   }
/*     */   
/*     */   public String getSender()
/*     */   {
/* 128 */     return "";
/*     */   }
/*     */   
/*     */   public int getItemCount() {
/* 132 */     return (int)getSize();
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   void updateSize(int countDelta, int deletedDelta)
/*     */     throws ServiceException
/*     */   {
/* 140 */     int delta = countDelta - deletedDelta;
/* 141 */     if ((delta == 0) || (!trackUnread())) {
/* 142 */       return;
/*     */     }
/* 144 */     markItemModified(16);
/*     */     
/* 146 */     this.mData.size = Math.max(0L, this.mData.size + delta);
/*     */   }
/*     */   
/*     */   protected void updateUnread(int delta, int deletedDelta)
/*     */     throws ServiceException
/*     */   {
/* 152 */     super.updateUnread(delta - deletedDelta, 0);
/*     */   }
/*     */   
/*     */ 
/*     */   boolean isTaggable()
/*     */   {
/* 158 */     return false;
/*     */   }
/*     */   
/*     */   boolean isCopyable()
/*     */   {
/* 163 */     return false;
/*     */   }
/*     */   
/*     */   boolean isMovable()
/*     */   {
/* 168 */     return false;
/*     */   }
/*     */   
/*     */   boolean isMutable()
/*     */   {
/* 173 */     return true;
/*     */   }
/*     */   
/*     */   boolean canHaveChildren()
/*     */   {
/* 178 */     return false;
/*     */   }
/*     */   
/*     */   boolean canTag(MailItem item) {
/* 182 */     return item.isTaggable();
/*     */   }
/*     */   
/*     */   public RetentionPolicy getRetentionPolicy()
/*     */   {
/* 187 */     return this.retentionPolicy;
/*     */   }
/*     */   
/*     */   public void setRetentionPolicy(RetentionPolicy rp) throws ServiceException {
/* 191 */     if (!canAccess((short)256)) {
/* 192 */       throw ServiceException.PERM_DENIED("you do not have admin rights to tag " + getName());
/*     */     }
/*     */     
/* 195 */     markItemModified(33554432);
/* 196 */     this.retentionPolicy = (rp == null ? new RetentionPolicy() : rp);
/* 197 */     saveMetadata();
/*     */   }
/*     */   
/*     */   public boolean isListed() {
/* 201 */     return this.isListed;
/*     */   }
/*     */   
/*     */   void setListed() throws ServiceException {
/* 205 */     if (!this.isListed) {
/* 206 */       this.isListed = true;
/* 207 */       saveMetadata();
/*     */     }
/*     */   }
/*     */   
/*     */   static Tag create(Mailbox mbox, int id, String requestedName, Color color, boolean listed) throws ServiceException {
/* 212 */     String name = validateItemName(requestedName);
/*     */     try
/*     */     {
/* 215 */       mbox.getTagByName(name);
/* 216 */       throw MailServiceException.ALREADY_EXISTS(name);
/*     */     }
/*     */     catch (MailServiceException.NoSuchItemException nsie) {
/* 219 */       MailItem.UnderlyingData data = new MailItem.UnderlyingData();
/* 220 */       data.id = id;
/* 221 */       data.type = MailItem.Type.TAG.toByte();
/* 222 */       data.folderId = 8;
/* 223 */       data.name = name;
/* 224 */       data.setSubject(name);
/* 225 */       data.metadata = encodeMetadata(color, 1, 1, null, listed);
/* 226 */       data.contentChanged(mbox);
/* 227 */       ZimbraLog.mailop.info("Adding Tag %s: id=%d.", new Object[] { name, Integer.valueOf(data.id) });
/* 228 */       DbTag.createTag(mbox, data, color, listed);
/*     */       
/* 230 */       Tag tag = new Tag(mbox, data);
/* 231 */       tag.finishCreation(null);
/* 232 */       return tag;
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public static Tag createPseudoRemoteTag(Mailbox mbox, String requestedName)
/*     */     throws ServiceException
/*     */   {
/* 241 */     String name = validateItemName(requestedName);
/*     */     try
/*     */     {
/* 244 */       mbox.getTagByName(name);
/* 245 */       throw MailServiceException.ALREADY_EXISTS(name);
/*     */     }
/*     */     catch (MailServiceException.NoSuchItemException nsie) {
/* 248 */       MailItem.UnderlyingData data = new MailItem.UnderlyingData();
/* 249 */       data.id = -32;
/* 250 */       data.type = MailItem.Type.TAG.toByte();
/* 251 */       data.folderId = 8;
/* 252 */       data.name = name;
/* 253 */       data.setSubject(name);
/* 254 */       data.metadata = null;
/*     */       
/*     */ 
/* 257 */       data.setFlags(data.getFlags() | Flag.BITMASK_UNCACHED);
/* 258 */       return new Tag(mbox, data);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   void alterUnread(boolean unread)
/*     */     throws ServiceException
/*     */   {
/* 272 */     if (unread) {
/* 273 */       throw ServiceException.INVALID_REQUEST("tags can only be marked read", null);
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/* 279 */     List<Integer> targets = new ArrayList();
/* 280 */     int delta = unread ? 1 : -1;
/* 281 */     for (MailItem.UnderlyingData data : DbTag.getUnreadMessages(this)) {
/* 282 */       Message msg = this.mMailbox.getMessage(data);
/* 283 */       if ((msg.checkChangeID()) || (!msg.canAccess((short)2))) {
/* 284 */         msg.updateUnread(delta, msg.isTagged(Flag.FlagInfo.DELETED) ? delta : 0);
/* 285 */         msg.metadataChanged();
/* 286 */         targets.add(Integer.valueOf(msg.getId()));
/*     */       }
/*     */     }
/*     */     
/*     */ 
/* 291 */     DbMailItem.alterUnread(this.mMailbox, targets, unread);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/* 296 */   private static final CharMatcher INVALID_TAG_CHARS = CharMatcher.anyOf(":\\");
/*     */   
/*     */   static String validateItemName(String name) throws ServiceException
/*     */   {
/* 300 */     if ((name == null) || (name != StringUtil.stripControlCharacters(name)) || (INVALID_TAG_CHARS.matchesAnyOf(name))) {
/* 301 */       throw MailServiceException.INVALID_NAME(name);
/*     */     }
/*     */     
/* 304 */     String trimmed = name.trim().replace('\t', ' ').replace('\r', ' ').replace('\n', ' ');
/* 305 */     if ((trimmed.isEmpty()) || (trimmed.length() > 255) || (trimmed.startsWith("\\"))) {
/* 306 */       throw MailServiceException.INVALID_NAME(name);
/*     */     }
/* 308 */     return trimmed;
/*     */   }
/*     */   
/*     */ 
/*     */   void rename(String name, Folder target)
/*     */     throws ServiceException
/*     */   {
/* 315 */     String originalName = getName();String newName = validateItemName(name);
/*     */     
/* 317 */     if (target.getId() != 8)
/* 318 */       throw MailServiceException.CANNOT_CONTAIN();
/* 319 */     if (originalName.equals(newName))
/* 320 */       return;
/* 321 */     if (!canAccess((short)2)) {
/* 322 */       throw ServiceException.PERM_DENIED("you do not have the required rights on the item");
/*     */     }
/*     */     
/* 325 */     if (ZimbraLog.mailop.isDebugEnabled()) {
/* 326 */       ZimbraLog.mailop.debug("renaming " + getMailopContext(this) + " to " + newName);
/*     */     }
/*     */     
/*     */ 
/* 330 */     markItemModified(4096);
/* 331 */     this.mData.name = newName;
/* 332 */     contentChanged();
/* 333 */     DbTag.renameTag(this);
/*     */     
/* 335 */     this.mMailbox.purge(MailItem.Type.MESSAGE);
/*     */     
/* 337 */     touchAllFolders();
/*     */   }
/*     */   
/*     */   void purgeCache(MailItem.PendingDelete info, boolean purgeItem) throws ServiceException
/*     */   {
/* 342 */     ZimbraLog.mailop.debug("Removing %s from all items.", new Object[] { getMailopContext(this) });
/*     */     
/* 344 */     DbTag.deleteTag(this);
/*     */     
/* 346 */     touchAllFolders();
/*     */     
/* 348 */     this.mMailbox.purge(MailItem.Type.MESSAGE);
/*     */     
/* 350 */     super.purgeCache(info, purgeItem);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   void touchAllFolders()
/*     */     throws ServiceException
/*     */   {
/* 358 */     for (Folder folder : this.mMailbox.listAllFolders()) {
/* 359 */       if (folder.getItemCount() > 0L) {
/* 360 */         folder.updateHighestMODSEQ();
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */   protected void saveTagCounts() throws ServiceException
/*     */   {
/* 367 */     DbTag.persistCounts(this);
/* 368 */     ZimbraLog.mailbox.debug("\"%s\": updating tag counts (s%d/u%d)", new Object[] { getName(), Integer.valueOf((int)this.mData.size), Integer.valueOf(this.mData.unreadCount) });
/*     */   }
/*     */   
/*     */   protected void saveMetadata(String ignored) throws ServiceException
/*     */   {
/* 373 */     metadataChanged();
/* 374 */     DbTag.saveMetadata(this);
/*     */   }
/*     */   
/*     */   void decodeMetadata(Metadata meta) throws ServiceException
/*     */   {
/* 379 */     super.decodeMetadata(meta);
/*     */     
/* 381 */     this.isListed = meta.getBool("lst", false);
/*     */     
/* 383 */     Metadata rp = meta.getMap("rp", true);
/* 384 */     if (rp != null) {
/* 385 */       this.retentionPolicy = RetentionPolicyManager.retentionPolicyFromMetadata(rp, true);
/*     */     } else {
/* 387 */       this.retentionPolicy = new RetentionPolicy();
/*     */     }
/*     */   }
/*     */   
/*     */   Metadata encodeMetadata(Metadata meta)
/*     */   {
/* 393 */     return encodeMetadata(meta, this.mRGBColor, this.mMetaVersion, this.mVersion, this.retentionPolicy, this.isListed);
/*     */   }
/*     */   
/*     */   public static String encodeMetadata(Color color, int metaVersion, int version, RetentionPolicy rp, boolean listed) {
/* 397 */     return encodeMetadata(new Metadata(), color, metaVersion, version, rp, listed).toString();
/*     */   }
/*     */   
/*     */   static Metadata encodeMetadata(Metadata meta, Color color, int metaVersion, int version, RetentionPolicy rp, boolean listed) {
/* 401 */     MailItem.encodeMetadata(meta, color, null, metaVersion, version, null);
/*     */     
/* 403 */     if ((rp != null) && (rp.isSet())) {
/* 404 */       meta.put("rp", RetentionPolicyManager.toMetadata(rp, true));
/*     */     }
/* 406 */     meta.put("lst", listed);
/*     */     
/* 408 */     return meta;
/*     */   }
/*     */   
/*     */   public String toString()
/*     */   {
/* 413 */     Objects.ToStringHelper helper = Objects.toStringHelper(this);
/* 414 */     appendCommonMembers(helper);
/* 415 */     return helper.toString();
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/mailbox/Tag.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */